package com.amos.muexamclient.sys.service.impl;

import com.amos.exception.BizExceptionEnum;
import com.amos.muexamclient.sys.entity.SysDeptEntity;
import com.amos.muexamclient.sys.mapper.SysDeptMapper;
import com.amos.muexamclient.sys.service.SysDeptService;
import com.amos.muexamclient.sys.service.dto.SysDeptDTO;
import com.amos.muexamclient.sys.service.dto.TreeSelect;
import com.amos.muexamcore.core.AbstractPageService;
import com.amos.muexamcore.core.BaseMapper;
import com.amos.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Copyright © 2018 五月工作室. All rights reserved.
 *
 * @Package com.amos.muexamclient.sys.service.impl
 * @ClassName SysDeptServiceImpl
 * @Description TODO
 * @Author Amos
 * @Modifier
 * @Date 2020-03-15 10:39:17
 * @Version 1.0
 **/
@Service
public class SysDeptServiceImpl extends AbstractPageService<SysDeptDTO, SysDeptEntity> implements SysDeptService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    /**
     * 条件查询
     *
     * @param dto 查询的条件
     */
    @Override
    public List<SysDeptDTO> list(SysDeptDTO dto) {
        return this.getMapper().select(dto);
    }

    /**
     * 返回BaseDao对象
     */
    @Override
    public BaseMapper<SysDeptEntity, SysDeptDTO> getMapper() {
        return sysDeptMapper;
    }

    /**
     * 保存之间的校验
     *
     * @param dto 保存的对象
     */
    @Override
    public void preValidate(SysDeptDTO dto) {
        this.validate(dto);
    }

    private void validate(SysDeptDTO dto) {
        List<SysDeptDTO> depts = this.sysDeptMapper.getDeptNameAndParentId(dto.getDeptName(), dto.getParentId());
        if (dto.isNew()) {
            if (!CollectionUtils.isEmpty(depts)) {
                BizExceptionEnum.DEFINED_EXCEPTION.definedMsg("新增部门'" + dto.getDeptName() + "'失败，部门名称已存在").throwException();
            }
        } else {
            if (!CollectionUtils.isEmpty(depts)) {
                SysDeptDTO dept = depts.get(0);
                if (!dto.getId().equals(dept.getId())) {
                    BizExceptionEnum.DEFINED_EXCEPTION.definedMsg("修改部门'" + dto.getDeptName() + "'失败，部门名称已存在").
                            throwException();
                }
            }
        }
    }

    /**
     * 添加子集数据
     *
     * @param id  主表ID
     * @param dto 主表DTO对象
     */
    @Override
    public void appendSubsidiary(String id, SysDeptDTO dto) {

    }

    @Override
    public List<TreeSelect> treeSelect(SysDeptDTO dto) {
        List<SysDeptDTO> list = this.select(dto);
        return list.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public List<SysDeptDTO> buildDeptTree(List<SysDeptDTO> depts) {
        List<SysDeptDTO> returnList = new ArrayList<SysDeptDTO>();
        List<String> tempList = new ArrayList<String>();
        for (SysDeptDTO dept : depts) {
            tempList.add(dept.getId());
        }
        for (Iterator<SysDeptDTO> iterator = depts.iterator(); iterator.hasNext(); ) {
            SysDeptDTO dept = (SysDeptDTO) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = depts;
        }
        return returnList;
    }

    private void recursionFn(List<SysDeptDTO> list, SysDeptDTO t) {
        // 得到子节点列表
        List<SysDeptDTO> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDeptDTO tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                Iterator<SysDeptDTO> it = childList.iterator();
                while (it.hasNext()) {
                    SysDeptDTO n = (SysDeptDTO) it.next();
                    recursionFn(list, n);
                }
            }
        }
    }

    private List<SysDeptDTO> getChildList(List<SysDeptDTO> list, SysDeptDTO t) {
        List<SysDeptDTO> tlist = new ArrayList<SysDeptDTO>();
        Iterator<SysDeptDTO> it = list.iterator();
        while (it.hasNext()) {
            SysDeptDTO n = (SysDeptDTO) it.next();
            if (StringUtils.isNullOrEmpty(n.getParentId()) && n.getParentId().equalsIgnoreCase(t.getId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    private boolean hasChild(List<SysDeptDTO> list, SysDeptDTO t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    @Override
    public Map<String, Object> roleDeptTreeselect(String id) {
        Map<String, Object> map = new HashMap<>();
        List<SysDeptDTO> depts = this.select(new SysDeptDTO());
        map.put("depts", this.buildDeptTree(depts));
        map.put("checkedKeys", this.selectDeptListByRoleId(id));
        return map;
    }

    private List<String> selectDeptListByRoleId(String id) {
        return sysDeptMapper.selectDeptListByRoleId(id);
    }

    @Override
    public String remove(String deptId) {
        return null;
    }

    @Override
    public boolean hasChildByDeptId(String deptId) {
        int result = this.sysDeptMapper.hasChildByDeptId(deptId);
        return result > 0 ? true : false;
    }

    @Override
    public boolean checkDeptExistUser(String deptId) {
        int result = this.sysDeptMapper.checkDeptExistUser(deptId);
        return result > 0 ? true : false;
    }
}
